import fs from 'fs';
import lodash from 'lodash';
const _path = process.cwd();
/**
 * 处理子频道和私聊消息
 */
async function dealMsg(e) {
  for (let val of command) {
    let msg = e.msg.content;
    if (!val.reg) {
      val.reg = 'noCheck';
    } else {
      // 去掉@机器人
      if (msg) {
        msg = msg.replace(`<@!${bot.id}>`, '').trim();
      }
    }
    if (new RegExp(val.reg).test(msg) || val.reg == 'noCheck') {
      let { type, name } = val;
      if (!KongApps[type] || !KongApps[type][name]) {
        logger.error(`请先export该方法：${type}.${name}`);
        return;
      }

      try {
        let res = await KongApps[type][name](e);
        if (res) {
          break;
        }
      } catch (error) {
        logger.error(`${type}.${name}`);
        logger.error(decodeURI(error.stack), error);
        break;
      }
    }
  }
}

//加载功能
async function loadApp(dir) {
  let KongApps = {};
  let command = [];
  for (let val of dir) {
    let readDir = fs.readdirSync(_path + `/lib/${val}`);
    readDir = readDir.filter(item => /.js$/.test(item));

    for (let v of readDir) {
      try {
        let tmp = await import(`./${val}/${v}`);
        if (!tmp.rule) continue;
        let type = v.replace('.js', '');
        KongApps[type] = tmp;
        for (let i in tmp.rule) {
          tmp.rule[i].type = type;
          tmp.rule[i].name = i;
          command.push(tmp.rule[i]);
        }
      } catch (error) {
        logger.error(`报错：${v}`);
        console.log(error);
        process.exit();
      }
    }
  }
  command = lodash.orderBy(command, ['priority'], ['asc']);

  global.KongApps = KongApps;
  global.command = command;
  global.GroupCommand = [];

  saveCommand(command);
}

// 加载Plugin
async function loadPlugin(dir) {
  let KongApps = global.KongApps || {};
  let command = global.command || [];

  for (let val of dir) {
    if (!fs.existsSync(_path + `/${val}/`)) {
      fs.mkdirSync(_path + `/${val}/`);
    }
    let readDir = fs.readdirSync(_path + `/${val}/`);
    for (let v of readDir) {
      if (!fs.existsSync(_path + `/${val}/${v}/index.js`)) {
        continue;
      }
      try {
        let tmp = await import(`../${val}/${v}/index.js`);
        let rules = tmp.rule;
        if (!rules) {
          continue;
        }
        if (typeof rules === 'function') {
          rules = rule();
        }
        let type = v.replace('.js', '');
        KongApps[type] = tmp;
        for (let i in rules) {
          rules[i].type = type;
          rules[i].name = i;
          rules[i]._plugin = type;
          command.push(tmp.rule[i]);
        }
      } catch (error) {
        if (global.debugView) {
          throw error;
        } else {
          logger.error(`报错：${v}`);
          console.log(error);
        }
        process.exit();
      }
    }
  }

  command = lodash.orderBy(command, ['priority'], ['asc']);

  global.KongApps = KongApps;
  global.command = command;

  saveCommand(command);
}

let fsTimeout = {};

//config热更新
async function hotLoad() {
  fs.watch('./config/config.js', async (event, filename) => {
    if (fsTimeout.config) {
      return;
    }
    fsTimeout.config = true;

    setTimeout(async () => {
      let config;
      try {
        config = (
          await import(`../config/config.js?version=${new Date().getTime()}`)
        ).config;
        global.cfg=config;
      } catch (err) {
        logger.error(`配置报错：config.js\n${err}`);
        fsTimeout.config = null;
        return;
      }


    }, 500);
  });
}

//app热更新
async function hotLoadApp(dir) {
  for (let val of dir) {
    fs.watch(`./lib/${val}`, async (event, filename) => {
      let re = new RegExp(`.js$`, 'i');
      if (fsTimeout[val] || !re.test(filename)) {
        return;
      }
      fsTimeout[val] = true;

      let type = filename.replace('.js', '');

      setTimeout(async () => {
        if (!fs.existsSync(`./lib/${val}/${filename}`)) {
          fsTimeout[val] = null;
          return;
        }
        let tmp;
        try {
          tmp = await import(
            `./${val}/${filename}?version=${new Date().getTime()}`
          );
        } catch (err) {
          logger.error(`报错${val}/${type}.js\n${err}`);
          fsTimeout[val] = null;
          return;
        }
        let rule = tmp.rule;
        if (!rule) {
          fsTimeout[val] = null;
          return;
        }
        for (let i in command) {
          if (type == command[i].type && rule[command[i].name]) {
            command[i] = {
              ...rule[command[i].name],
              type: type,
              name: command[i].name
            };
            delete rule[command[i].name];
          }
        }
        if (Object.keys(rule).length != 0) {
          for (let i in rule) {
            command.push({ ...rule[i], type: type, name: i });
          }
        }

        command = lodash.orderBy(command, ['priority'], ['asc']);
        KongApps[type] = tmp;

        logger.mark(`更新${val}/${type}.js完成`);
        fsTimeout[val] = null;
      }, 500);
    });
  }
}

//生成命令json
async function saveCommand(command) {
  let data = {
    dec: '命令总览json，只是查看，修改不起作用，需要到具体文件修改'
  };
  for (let val of command) {
    if (!data[val.type]) {
      data[val.type] = {};
    }

    data[val.type][val.name] = {
      reg: val.reg,
      priority: val.priority,
      describe: val.describe
    };
  }

  fs.writeFileSync('config/command.json', JSON.stringify(data, '', '\t'));
}

async function init() {
  //初始化功能
  await loadApp(['example','app']);

  await loadPlugin(['plugins']);

  //配置config热加载
  hotLoad();
  //功能热加载
  hotLoadApp(['example','app']);
}

export default {
  init,
  dealMsg
};
